#include "infopanel.h"
#include <QDebug>
#include <QtMath>
#include <QDateTime>

InfoPanel::InfoPanel(QWidget *parent) : QWidget(parent)
{
    // 创建主布局
    mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(2, 2, 2, 2);
    mainLayout->setSpacing(2);
    
    // 创建窗口信息组
    windowInfoGroup = new QGroupBox("窗口信息", this);
    QVBoxLayout *windowInfoLayout = new QVBoxLayout(windowInfoGroup);
    windowInfoLayout->setContentsMargins(3, 3, 3, 3);
    windowInfoLayout->setSpacing(2);
    
    // 创建窗口信息表格
    windowInfoTable = new QTableWidget(this);
    windowInfoTable->setColumnCount(2);
    windowInfoTable->setHorizontalHeaderLabels(QStringList() << "时间" << "消息");
    windowInfoTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
    windowInfoTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
    windowInfoTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    windowInfoTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    windowInfoTable->setAlternatingRowColors(true);
    
    windowInfoLayout->addWidget(windowInfoTable);
    
    // 创建图文警情组
    graphicAlarmGroup = new QGroupBox("实时环境播报", this);
    QVBoxLayout *graphicAlarmLayout = new QVBoxLayout(graphicAlarmGroup);
    graphicAlarmLayout->setContentsMargins(3, 3, 3, 3);
    graphicAlarmLayout->setSpacing(2);
    
    // 创建图文警情列表
    graphicAlarmList = new QListWidget(this);
    graphicAlarmList->setAlternatingRowColors(true);
    
    graphicAlarmLayout->addWidget(graphicAlarmList);
    
    // 创建日志显示组
    logGroup = new QGroupBox("系统日志", this);
    QVBoxLayout *logLayout = new QVBoxLayout(logGroup);
    logLayout->setContentsMargins(3, 3, 3, 3);
    logLayout->setSpacing(2);
    
    // 创建日志显示区域
    logDisplay = new QTextEdit(this);
    logDisplay->setReadOnly(true);
    
    // 创建查询控件
    dateComboBox = new QComboBox(this);
    levelComboBox = new QComboBox(this);
    queryLogButton = new QPushButton("查询日志", this);
    refreshLogButton = new QPushButton("刷新日志", this);
    exportLogButton = new QPushButton("导出日志", this);
    logPathLabel = new QLabel("日志路径: log/", this);
    
    // 设置日期下拉框默认选项
    dateComboBox->addItem("今天");
    dateComboBox->addItem("昨天");
    dateComboBox->addItem("前天");
    dateComboBox->addItem("最近一周");
    
    // 设置日志级别下拉框选项
    levelComboBox->addItem("全部");
    levelComboBox->addItem("INFO");
    levelComboBox->addItem("WARNING");
    levelComboBox->addItem("ERROR");
    
    // 创建按钮布局
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->setSpacing(3);
    buttonLayout->addWidget(new QLabel("日期:", this));
    buttonLayout->addWidget(dateComboBox);
    buttonLayout->addWidget(new QLabel("级别:", this));
    buttonLayout->addWidget(levelComboBox);
    buttonLayout->addWidget(queryLogButton);
    buttonLayout->addWidget(refreshLogButton);
    buttonLayout->addWidget(exportLogButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(logPathLabel);
    
    logLayout->addLayout(buttonLayout);
    logLayout->addWidget(logDisplay);
    
    // 添加到主布局
    mainLayout->addWidget(windowInfoGroup);
    mainLayout->addWidget(graphicAlarmGroup);
    mainLayout->addWidget(logGroup);
    
    // 连接按钮信号
    connect(refreshLogButton, &QPushButton::clicked, this, [this]() {
        loadLogFile(getCurrentDate());
    });
    
    connect(exportLogButton, &QPushButton::clicked, this, [this]() {
        QString fileName = QFileDialog::getSaveFileName(this, "导出日志", 
                                                       QString("log_%1.txt").arg(getCurrentDate()),
                                                       "Text Files (*.txt)");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                QTextStream out(&file);
                out << logDisplay->toPlainText();
                file.close();
            }
        }
    });
    
    // 连接查询按钮信号到槽函数
    connect(queryLogButton, &QPushButton::clicked, this, &InfoPanel::queryLogFile);
    
    // 默认加载今天的日志
    loadLogFile(getCurrentDate());
    
    // 设置组的大小策略
    windowInfoGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    graphicAlarmGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    // 设置初始可见性状态
    // 默认显示窗口信息和图文警情，隐藏系统日志
    windowInfoGroup->setVisible(true);
    graphicAlarmGroup->setVisible(true);
    logGroup->setVisible(false);


    addGraphicAlarm(QString("12341234"));

    addGraphicAlarm(QString("10002000"));

}

InfoPanel::~InfoPanel()
{
}

void InfoPanel::addWindowMessage(const QString &time, const QString &msg)
{
    // 在第0行插入新行
    int row = 0;
    windowInfoTable->insertRow(row);

    QTableWidgetItem *timeItem = new QTableWidgetItem(time);
    QTableWidgetItem *msgItem = new QTableWidgetItem(msg);

    // 设置文本对齐方式以支持多行显示
    msgItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft);

    // 将项目插入到第0行
    windowInfoTable->setItem(row, 0, timeItem);
    windowInfoTable->setItem(row, 1, msgItem);

    // 调整行高以适应内容
    windowInfoTable->resizeRowToContents(row);

    // 可选：滚动到顶部或保持视图位置
    windowInfoTable->scrollToTop();

}

// ADC值转温度函数
double adcToTemperature(int adcValue) {
    // 1. 将ADC值转换为电压
    double voltage = (adcValue * 3.3) / 4095;

    // 2. 计算热敏电阻当前阻值（基于分压电路）
    double r_ntc = (voltage * 10000.0) / (3.3 - voltage);

    // 3. 使用Steinhart-Hart方程计算温度（开尔文）
    double steinhart;
    steinhart = r_ntc / 10000.0;                       // R/R0
    steinhart = log(steinhart);                   // ln(R/R0)
    steinhart /= 3950.0;                            // 1/B * ln(R/R0)
    steinhart += 1.0 / 298.15;                        // + (1/T0)
    steinhart = 1.0 / steinhart;                  // 取倒数得到开尔文温度

    // 4. 转换为摄氏度并返回
    return steinhart - 273.15;
}

// ADC值转光照强度函数
double adcToLux(int adcValue) {
    // 1. 将ADC值转换为电压
    double voltage = (adcValue * 3.3) / 4095;

    // 2. 计算光敏电阻当前阻值
    double r_ldr = (voltage * 10000.0) / (3.3 - voltage);

    // 3. 使用光敏电阻的特性公式计算光照强度
    // 光敏电阻的电阻-光照关系：R = R10 * (10 / Lux)^Gamma
    // 转换为：Lux = 10 * (R10 / R_ldr)^(1/Gamma)
    double lux = 10.0 * qPow(50000.0 / r_ldr, 1.0 / 0.7);

    return lux;
}



void InfoPanel::addGraphicAlarm( const QString &message)
{
    // 确保列表始终只有两行（光照强度和温度），并且正确显示在指定位置
     QString lightintensity = message.left(4); 
     QString temperature = message.right(4); 
 
     // 设置文本 
     QString itemText1 = QString("光照强度 : %1").arg(adcToLux(lightintensity.toInt())); 
     QString itemText2 = QString("温度 : %1").arg(adcToTemperature(temperature.toInt())); 
 
     // 如果列表中已存在项目，更新它们；否则创建新项目
     QListWidgetItem *item1;
     QListWidgetItem *item2;
 
     if (graphicAlarmList->count() >= 2) {
         // 更新现有项目
         item1 = graphicAlarmList->item(0);
         item2 = graphicAlarmList->item(1);
         item1->setText(itemText1);
         item2->setText(itemText2);
     } else {
         // 清空列表并重新添加项目，确保顺序正确
         graphicAlarmList->clear();
         
         // 先添加光照强度信息（第0行）
         item1 = new QListWidgetItem(itemText1);
         graphicAlarmList->insertItem(0, item1);
         
         // 再添加温度信息（第1行）
         item2 = new QListWidgetItem(itemText2);
         graphicAlarmList->insertItem(1, item2);
     }
 
     // 重置颜色
     item1->setForeground(Qt::black);
     item2->setForeground(Qt::black);
 
     // 根据条件设置警告颜色
     if(adcToTemperature(temperature.toInt()) > 40){ 
         item2->setForeground(Qt::red); // 温度警告
         addWindowMessage(QDateTime::currentDateTime().toString() , QString("温度预警!!")); 
     } 
 
     if(adcToLux(lightintensity.toInt()) >  100000){ 
         item1->setForeground(Qt::red); // 光照强度警告
         addWindowMessage(QDateTime::currentDateTime().toString() , QString("强光预警!!")); 
     }
}

void InfoPanel::setCurrentTab(const QString &tabName)
{
    // 这里可以添加标签页切换的逻辑
    // 暂时只打印日志
    qDebug() << "切换到标签页:" << tabName;
}

void InfoPanel::clearWindowMessages()
{
    // TODO: 清空窗口信息表格
    // 需要清除windowInfoTable中的所有行
}

void InfoPanel::clearGraphicAlarms()
{
    // TODO: 清空图文警情列表
    // 需要清除graphicAlarmList中的所有项
}

int InfoPanel::getWindowMessageCount() const
{
    // TODO: 获取窗口信息数量
    // 需要返回windowInfoTable的行数
    return 0;
}

int InfoPanel::getGraphicAlarmCount() const
{
    // TODO: 获取图文警情数量
    // 需要返回graphicAlarmList的项目数
    return 0;
}

QString InfoPanel::getCurrentTab() const
{
    // TODO: 获取当前标签页名称
    // 需要返回当前活动的标签页名称
    return "";
}

void InfoPanel::onWindowInfoDoubleClicked(int row, int column)
{
    // TODO: 窗口信息表格项被双击
    // 需要发出messageClicked信号
    (void)row; // 避免未使用参数警告
    (void)column; // 避免未使用参数警告
}

void InfoPanel::onGraphicAlarmClicked(QListWidgetItem *item)
{
    // TODO: 图文警情项被点击
    // 需要发出alarmViewed信号
    (void)item; // 避免未使用参数警告
}

void InfoPanel::setWindowInfoVisible(bool visible)
{
    // 设置窗口信息组的可见性
    windowInfoGroup->setVisible(visible);
}

void InfoPanel::setGraphicAlarmVisible(bool visible)
{
    // 设置图文警情组的可见性
    graphicAlarmGroup->setVisible(visible);
}

void InfoPanel::loadLogFile(const QString &date)
{
    QString logPath = "log";
    QString fileName = QString("%1/%2.txt").arg(logPath).arg(date);
    
    QFile file(fileName);
    if (!file.exists()) {
        logDisplay->setPlainText(QString("日志文件不存在: %1").arg(fileName));
        return;
    }
    
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        logDisplay->setPlainText(QString("无法打开日志文件: %1").arg(fileName));
        return;
    }
    
    QTextStream in(&file);
    QString content = in.readAll();
    file.close();
    
    logDisplay->setPlainText(content);
}

QString InfoPanel::getCurrentDate() const
{
    return QDate::currentDate().toString("yyyy-MM-dd");
}

void InfoPanel::queryLogFile() {
    // 获取选择的日期选项
    QString dateOption = dateComboBox->currentText();
    QString selectedLevel = levelComboBox->currentText();
    
    QString logContent;
    
    // 处理最近一周的特殊情况
    if (dateOption == "最近一周") {
        logContent = readLogFilesForWeek();
    } else {
        // 获取选择的日期
        QString selectedDate = getSelectedDate();
        // 加载日志文件
        logContent = readLogFile(selectedDate);
    }
    
    // 根据日志级别过滤日志
    if (selectedLevel != "全部") {
        logContent = filterLogByLevel(logContent, selectedLevel);
    }
    
    // 显示过滤后的日志
    logDisplay->setPlainText(logContent);
}

QString InfoPanel::getSelectedDate()
{
    QString dateOption = dateComboBox->currentText();
    QDate currentDate = QDate::currentDate();
    
    if (dateOption == "今天") {
        return currentDate.toString("yyyy-MM-dd");
    } else if (dateOption == "昨天") {
        return currentDate.addDays(-1).toString("yyyy-MM-dd");
    } else if (dateOption == "前天") {
        return currentDate.addDays(-2).toString("yyyy-MM-dd");
    } else if (dateOption == "最近一周") {
        // 返回一周前的日期
        return currentDate.addDays(-6).toString("yyyy-MM-dd");
    }
    
    return currentDate.toString("yyyy-MM-dd");
}

QString InfoPanel::readLogFile(const QString &date) {
    QString logPath = "log";
    QString fileName = QString("%1/%2.txt").arg(logPath).arg(date);
    
    QFile file(fileName);
    if (!file.exists()) {
        return QString("日志文件不存在: %1").arg(fileName);
    }
    
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return QString("无法打开日志文件: %1").arg(fileName);
    }
    
    QTextStream in(&file);
    QString content = in.readAll();
    file.close();
    
    return content;
}

QString InfoPanel::readLogFilesForWeek() {
    QString logPath = "log";
    QString result;
    
    // 获取最近一周的日期
    QDate currentDate = QDate::currentDate();
    for (int i = 6; i >= 0; i--) {
        QDate date = currentDate.addDays(-i);
        QString dateStr = date.toString("yyyy-MM-dd");
        QString fileName = QString("%1/%2.txt").arg(logPath).arg(dateStr);
        
        QFile file(fileName);
        if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream in(&file);
            QString content = in.readAll();
            file.close();
            
            // 在每个文件的内容前添加日期标题
            if (!content.isEmpty()) {
                result += QString("========== %1 ==========\n").arg(dateStr);
                result += content;
                result += "\n";
            }
        }
    }
    
    if (result.isEmpty()) {
        result = "最近一周没有日志文件";
    }
    
    return result;
}

QString InfoPanel::filterLogByLevel(const QString &logContent, const QString &level)
{
    QStringList lines = logContent.split('\n');
    QStringList filteredLines;
    
    for (const QString &line : lines) {
        // 检查行是否包含指定的日志级别
        if (line.contains(QString("[%1]").arg(level))) {
            filteredLines.append(line);
        }
    }
    
    return filteredLines.join('\n');
}

void InfoPanel::setLogVisible(bool visible)
{
    // 设置日志显示组的可见性
    logGroup->setVisible(visible);
}
